using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using Kingdee.BOS.Util;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;


namespace CZ.PAEZ.SaleManager.FormPlugIns
{
    [Description("生产订单表单插件")]
    [HotUpdate]
    public class ProMoOrder : AbstractBillPlugIn
    {

        public override void DataChanged(DataChangedEventArgs e)
        {
            base.DataChanged(e);
            switch(e.Field.Key) 
            {
                case "FMaterialId":
                    Act_DC_CheckMtlLotOnlyOneForRow(e);
                    break;
                case "FLot":
                    Act_DC_CheckMtlLotOnlyOneForRow(e);
                    break;
            }
        }

        public override void BeforeDoOperation(BeforeDoOperationEventArgs e)
        {
            base.BeforeDoOperation(e);
            switch(e.Operation.FormOperation.Operation.ToUpperInvariant())
            {
                case "SAVE":
                    Act_BDP_BeforeSave(e);
                    break;
            }
        }


        /// <summary>
        /// 行中物料、批号变动时是否重复
        /// </summary>
        /// <param name="e"></param>
        private void Act_DC_CheckMtlLotOnlyOneForRow(DataChangedEventArgs e)
        {
            // 排除返工订单
            string FBillType = (this.Model.GetValue("FBillType") as DynamicObject)?["Id"].ToString();
            // 汇报入库-返工生产 || 工序汇报入库-返工生产
            if ("0e74146732c24bec90178b6fe16a2d1c".Equals(FBillType) || "5f93b1da667404".Equals(FBillType)) return;

            int i = e.Row;
            string mId_i = (this.Model.GetValue("FMaterialId", i) as DynamicObject)?["Id"].ToString();
            string lot_i = this.Model.GetValue("FLot", i)?.ToString();
            if(mId_i.IsNullOrEmptyOrWhiteSpace() || lot_i.IsNullOrEmptyOrWhiteSpace())
            {
                return;
            }
            int count = this.Model.GetEntryRowCount("FTreeEntity");
            for (var j = 0; j < count; j++)
            {
                if(j == e.Row) continue;
                string mId_j = (this.Model.GetValue("FMaterialId", j) as DynamicObject)?["Id"].ToString();
                string lot_j = this.Model.GetValue("FLot", j)?.ToString();
                if(mId_i.Equals(mId_j) && lot_i.Equals(lot_j))
                {
                    this.View.ShowErrMessage($"第{i+1}和{j+1}行的物料和批号重复！");
                    return;
                }
            }
            if(CheckMtlLotOnlyOne(i))
            {
                this.View.ShowErrMessage($"第{i+1}行中的物料和批号在生产订单中已经存在！");
            }
        }


        /// <summary>
        /// 保存前校验物料及批号的唯一性
        /// </summary>
        /// <param name="e"></param>
        private void Act_BDP_BeforeSave(BeforeDoOperationEventArgs e)
        {
            // 组织为优科时不作限制
            string orgId = (this.Model.GetValue("FPrdOrgId") as DynamicObject)?["Number"].ToString() ?? "";
            if (orgId.Equals("YK")) return;
            // 排除返工订单
            string FBillType = (this.Model.GetValue("FBillType") as DynamicObject)?["Id"].ToString();
            // 汇报入库-返工生产 || 工序汇报入库-返工生产
            if ("0e74146732c24bec90178b6fe16a2d1c".Equals(FBillType) || "5f93b1da667404".Equals(FBillType)) return;

            int count = this.Model.GetEntryRowCount("FTreeEntity");
            // 1、检查本单中是否有物料-批号重复的行
            for(int i = 0; i < count - 1; i++)
            {
                string mId_i = (this.Model.GetValue("FMaterialId", i) as DynamicObject)?["Id"].ToString();
                string lot_i = this.Model.GetValue("FLot", i)?.ToString();
                if(mId_i.IsNullOrEmptyOrWhiteSpace() || lot_i.IsNullOrEmptyOrWhiteSpace())
                {
                    continue;
                }
                for (int j = i + 1; j < count; j++)
                {
                    string mId_j = (this.Model.GetValue("FMaterialId", j) as DynamicObject)?["Id"].ToString();
                    string lot_j = this.Model.GetValue("FLot", j)?.ToString();
                    if(mId_i.Equals(mId_j) && lot_i.Equals(lot_j))
                    {
                        e.Cancel = true;
                        this.View.ShowErrMessage($"第{i+1}和{j+1}行的物料和批号重复！");
                        return;
                    }

                }
            }
            // 2、检查已保存订单中是否有物料-批号重复的行
            var list = new List<int>();
            for (int i = 0; i < count; i++)
            {
                if(CheckMtlLotOnlyOne(i)) list.Add(i+1);
            }
            if(list.Count > 0) 
            {
                this.View.ShowErrMessage($"第{string.Join(", ", list)}行中的物料和批号在生产订单中已经存在！");
                e.Cancel = true;
            }
        }


        /// <summary>
        /// 检查生产订单中物料和批号的唯一性
        /// </summary>
        /// <param name="i">订单行号</param>
        /// <returns></returns>
        private bool CheckMtlLotOnlyOne(int i)
        {
            string materialId = (this.Model.GetValue("FMaterialId", i) as DynamicObject)?["Id"].ToString();
            string lot = this.Model.GetValue("FLot", i)?.ToString();
            if(materialId.IsNullOrEmptyOrWhiteSpace() || lot.IsNullOrEmptyOrWhiteSpace()) 
            {
                return false;
            }
            string fid = "0";
            string status = this.Model.GetValue("FDocumentStatus").ToString();
            // 非暂存的单子保存时要排除掉本单
            if(!"Z".Equals(status)) fid = this.Model.DataObject["Id"].ToString();

            string sql = string.Format(@"select FEntryId from T_PRD_MOENTRY me
inner join T_BD_LotMaster lm on lm.FLOTID=me.FLot
where me.FMaterialId={0} and lm.FNumber='{1}' and me.FID<>{2}", materialId, lot, fid);
            var result = DBUtils.ExecuteDynamicObject(Context, sql);
            
            return result.Count > 0;
        }
    }
}
